package com.example.common

import android.os.Build
import android.os.Environment
import android.util.Log
import java.io.File
import java.io.FileWriter
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import kotlin.concurrent.thread

/**
 * 日志工具类，支持多种日志级别、线程信息显示、调用位置追踪和日志写入文件
 */
object Logger {
    // 日志级别
    enum class Level {
        VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, NONE
    }

    // 默认日志标签
    private const val DEFAULT_TAG = "Logger"
    
    // 日志级别控制
    var logLevel = Level.VERBOSE
        private set
    
    // 是否显示线程信息
    var showThreadInfo = true
        private set
    
    // 是否显示调用位置
    var showCallerInfo = true
        private set
    
    // 是否写入文件
    var writeToFile = false
        private set
    
    // 日志文件保存路径
    private var logFileDir: String? = null
    
    // 日志文件前缀
    private const val LOG_FILE_PREFIX = "log_"
    
    // 日志文件后缀
    private const val LOG_FILE_SUFFIX = ".txt"
    
    // 日期格式
    private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault())
    
    // 调用栈索引，用于获取调用位置
    private const val CALL_STACK_INDEX = 4

    /**
     * 初始化日志配置
     */
    fun init(
        logLevel: Level = Level.VERBOSE,
        showThreadInfo: Boolean = true,
        showCallerInfo: Boolean = true,
        writeToFile: Boolean = false,
        logDir: String? = null
    ) {
        this.logLevel = logLevel
        this.showThreadInfo = showThreadInfo
        this.showCallerInfo = showCallerInfo
        this.writeToFile = writeToFile
        
        if (writeToFile) {
            logFileDir = if (logDir.isNullOrEmpty()) {
                // 默认存储路径
                Environment.getExternalStorageDirectory()
                    .absolutePath + File.separator + "Android" + File.separator + "data" + 
                    File.separator + "com.example.logger" + File.separator + "logs"
            } else {
                logDir
            }
            
            // 创建日志目录
            createLogDir()
        }
    }

    /**
     * 创建日志目录
     */
    private fun createLogDir() {
        logFileDir?.let { dirPath ->
            val dir = File(dirPath)
            if (!dir.exists()) {
                dir.mkdirs()
            }
        }
    }

    /**
     * 获取当前日志文件
     */
    private fun getLogFile(): File? {
        logFileDir?.let { dirPath ->
            val date = SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(Date())
            val fileName = LOG_FILE_PREFIX + date + LOG_FILE_SUFFIX
            return File(dirPath, fileName)
        }
        return null
    }

    /**
     * 获取调用位置信息
     */
    private fun getCallerInfo(): String {
        val stackTrace = Thread.currentThread().stackTrace
        if (stackTrace.size > CALL_STACK_INDEX) {
            val element = stackTrace[CALL_STACK_INDEX]
            return "${element.className.substringAfterLast('.')}.${element.methodName}(${element.fileName}:${element.lineNumber})"
        }
        return "Unknown"
    }

    /**
     * 获取线程信息
     */
    private fun getThreadInfo(): String {
        val thread = Thread.currentThread()
        return "Thread[${thread.name},${thread.priority},${thread.threadGroup?.name}]"
    }

    /**
     * 构建日志内容
     */
    private fun buildLogContent(tag: String, level: Level, message: String): String {
        val sb = StringBuilder()
        
        // 添加时间
        sb.append("[${dateFormat.format(Date())}] ")
        
        // 添加日志级别
        sb.append("[${level.name}] ")
        
        // 添加标签
        sb.append("[$tag] ")
        
        // 添加线程信息
        if (showThreadInfo) {
            sb.append("${getThreadInfo()} ")
        }
        
        // 添加调用位置
        if (showCallerInfo) {
            sb.append("${getCallerInfo()} ")
        }
        
        // 添加日志消息
        sb.append(": $message")
        
        return sb.toString()
    }

    /**
     * 写入日志到文件
     */
    private fun writeLogToFile(content: String) {
        if (!writeToFile) return
        
        thread(isDaemon = true) {
            val logFile = getLogFile() ?: return@thread
            
            try {
                FileWriter(logFile, true).use { writer ->
                    writer.write(content)
                    writer.write("\n")
                    writer.flush()
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

    /**
     * 打印VERBOSE级别日志
     */
    fun v(tag: String = DEFAULT_TAG, message: String) {
        if (logLevel > Level.VERBOSE) return
        val content = buildLogContent(tag, Level.VERBOSE, message)
        Log.v(tag, content)
        writeLogToFile(content)
    }

    /**
     * 打印DEBUG级别日志
     */
    fun d(tag: String = DEFAULT_TAG, message: String) {
        if (logLevel > Level.DEBUG) return
        val content = buildLogContent(tag, Level.DEBUG, message)
        Log.d(tag, content)
        writeLogToFile(content)
    }

    /**
     * 打印INFO级别日志
     */
    fun i(tag: String = DEFAULT_TAG, message: String) {
        if (logLevel > Level.INFO) return
        val content = buildLogContent(tag, Level.INFO, message)
        Log.i(tag, content)
        writeLogToFile(content)
    }

    /**
     * 打印WARN级别日志
     */
    fun w(tag: String = DEFAULT_TAG, message: String) {
        if (logLevel > Level.WARN) return
        val content = buildLogContent(tag, Level.WARN, message)
        Log.w(tag, content)
        writeLogToFile(content)
    }

    /**
     * 打印ERROR级别日志
     */
    fun e(tag: String = DEFAULT_TAG, message: String) {
        if (logLevel > Level.ERROR) return
        val content = buildLogContent(tag, Level.ERROR, message)
        Log.e(tag, content)
        writeLogToFile(content)
    }

    /**
     * 打印ERROR级别日志，包含异常信息
     */
    fun e(tag: String = DEFAULT_TAG, message: String, throwable: Throwable) {
        if (logLevel > Level.ERROR) return
        val content = buildLogContent(tag, Level.ERROR, "$message\n${Log.getStackTraceString(throwable)}")
        Log.e(tag, content)
        writeLogToFile(content)
    }

    /**
     * 打印ASSERT级别日志
     */
    fun a(tag: String = DEFAULT_TAG, message: String) {
        if (logLevel > Level.ASSERT) return
        val content = buildLogContent(tag, Level.ASSERT, message)
        Log.wtf(tag, content)
        writeLogToFile(content)
    }

    /**
     * 打印长日志，解决Android日志长度限制问题
     */
    fun longD(tag: String = DEFAULT_TAG, message: String) {
        if (logLevel > Level.DEBUG) return
        
        // Android日志系统有长度限制，超过4000字符会被截断
        val maxLength = 4000
        if (message.length <= maxLength) {
            d(tag, message)
            return
        }
        
        var index = 0
        while (index < message.length) {
            val end = Math.min(index + maxLength, message.length)
            d(tag, message.substring(index, end))
            index = end
        }
    }

    /**
     * 清除所有日志文件
     */
    fun clearLogFiles(): Boolean {
        logFileDir?.let { dirPath ->
            val dir = File(dirPath)
            if (dir.exists() && dir.isDirectory) {
                dir.listFiles()?.forEach { file ->
                    if (file.name.startsWith(LOG_FILE_PREFIX) && file.name.endsWith(LOG_FILE_SUFFIX)) {
                        file.delete()
                    }
                }
                return true
            }
        }
        return false
    }
}
